package com.czh.config;

import com.czh.constant.CommonConstant;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.retry.MessageRecoverer;
import org.springframework.amqp.rabbit.retry.RepublishMessageRecoverer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 消息消费失败后在向error.exchange发送一次消息来处理错误消息 (配置 RabbitMQ 的死信交换机（Dead Letter Exchange，DLX）和死信队列（Dead Letter Queue，DLQ）)
 *
 * @author chenzhihua
 * @Date 2024/5/16
 */
@Configuration
@ConditionalOnProperty(name = "spring.rabbitmq.listener.simple.retry.enabled", havingValue = "true")
public class ErrorMessageConfig {
    /**
     * 异常消息直连交换机
     *
     * @return
     */
    @Bean(name = "error.exchange")
    public DirectExchange errorMessageExchange() {
        return new DirectExchange(CommonConstant.ERROR_EXCHANGE_NAME);
    }

    /**
     * 异常队列
     *
     * @return
     */
    @Bean(name = "error-queue")
    public Queue errorQueue() {
        return new Queue(CommonConstant.ERROR_QUEUE);
    }

    /**
     * 绑定交换机和队列并指定routekey
     *
     * @return
     */
    @Bean
    public Binding errorBinding() {
        return BindingBuilder.bind(errorQueue()).to(errorMessageExchange()).with("error");
    }

    /**
     * 定义一个RepublishMessageRecoverer，关联队列和交换机
     *
     * @param rabbitTemplate
     * @return
     */
    @Bean
    public MessageRecoverer republishMessageRecover(RabbitTemplate rabbitTemplate) {
        return new RepublishMessageRecoverer(rabbitTemplate, CommonConstant.ERROR_EXCHANGE_NAME, "error");
    }
}
